#include "xmlparser.h"

XMLParser::XMLParser(const char *xmlFilename){
	if (FileChecker::verify(xmlFilename))
		throw std::runtime_error("Cannot open xml file");	
    this->xmlFilename = xmlFilename;
    this->parsed = false;
    this->document = NULL;
    this->rootNode = NULL;
}

XMLParser::~XMLParser(){
	xmlFreeDoc(this->document);
	this->document = NULL;
   	xmlCleanupParser();	  
}

const char *XMLParser::getXMLFilename(){
	 return this->xmlFilename;

}

void XMLParser::parse() {
	
	if ( this->parsed ) {
		this->parsed = false;
		/* set used memory free - avoid memory leak */
		xmlFreeDoc(this->document);
		this->document = NULL;
	   	xmlCleanupParser();
 	 } 
	 /* Create a XML Parser */
	 this->document = xmlParseFile(this->xmlFilename);
	
	 if (this->document == NULL) {
		throw std::runtime_error("XML file is invalid!");		
    	exit(1);
	 }
	  /* get the root node */
	  this->rootNode = xmlDocGetRootElement(this->document);
	
	  if (this->rootNode == NULL) {
		throw std::runtime_error("XML file is empty!");		
	  }

	  this->parsed = true;

}

const char *XMLParser::getParameter(const char *nodeName, const char *attributeName, const char *elementName) {
	const char *propertyValue = NULL;
	propertyValue =  this->getParameter(this->rootNode, nodeName, attributeName, elementName);

	if (propertyValue == NULL)  {
		char *message = new char[200];
		sprintf(message, "Node %s or attribute %s does not exist!", nodeName, attributeName);
		throw std::runtime_error(message);
	}
	
	return propertyValue;	
}

const char *XMLParser::getParameter(xmlNode *node_curr ,const char *nodeName, const char *attributeName, const char *elementName){
	if (!this->parsed) throw std::runtime_error("Need to parse the XML file by calling the method \"parse()\"");

	xmlNode *n = NULL;
	const char *prop = NULL;

	for (n = node_curr; n; n = n->next) {
		if ((n->type==XML_ELEMENT_NODE) && (!strcmp(nodeName,(char *)n->name)) && ( (elementName==NULL) || (!strcmp(elementName,(const char *) xmlGetProp(n,(xmlChar *)NAME))) ) ) {
			prop = (const char *) xmlGetProp(n,(xmlChar *)attributeName);
			break;
		}
		prop = getParameter(n->children, nodeName,attributeName, elementName);
		if (prop) break;
	}

	return prop;

}
